<script setup lang="ts">
  import type { FormActionType, FormColumn, SubmitterProps } from './types/index';
  import type { GridProps, FormProps } from 'naive-ui';
  import { isArray, isNullOrUnDef } from '@/utils/is';
  import LabelMessageVue from './components/LabelMessage.vue';
  import FormComponent from './components/FormComponent/index.vue';
  import useForm from './hooks/useForm';
  import { ref, reactive, computed, onMounted } from 'vue';
  import Actions from './components/Actions.vue';
  const formModel = reactive<Recordable>({});
  const defaultFormModel = reactive<Recordable>({});
  const formRef = ref<FormActionType | null>(null);

  interface Props {
    columns: FormColumn[];
    submitter?: SubmitterProps;
    gridProps?: GridProps;
    formProps?: FormProps;
  }

  const props = withDefaults(defineProps<Props>(), {
    gridProps: () => ({ cols: '1 s:1 m:2 l:4 xl:4 2xl:4', collapsed: true }),
    submitter: () => ({
      show: true,
      searchConfig: {
        submitText: '查询',
        resetText: '重置',
      },
      submitButtonProps: {},
      resetButtonProps: {},
    }),
  });
  const collapsed = ref(props.gridProps.collapsed ?? true);
  const gridPropsInfo = computed(() => {
    // grid Props 属性
    return {
      ...props.gridProps,
      collapsed: collapsed.value,
    };
  });

  const formProps = computed(() => {
    const defaultProps = {
      labelWidth: 80,
      responsive: 'screen',
      layout: 'inline',
      size: 'medium',
      labelPlacement: 'left',
      isFull: true,
      collapsedRows: 1,
    };
    const rules = {} as any;
    props.columns?.forEach((item) => {
      if (item.rules && isArray(item.rules)) {
        rules[item.key] = item.rules;
      }
    });
    return {
      rules,
      ...defaultProps,
      ...props.formProps,
    };
  });

  const initDefault = () => {
    props.columns?.forEach((item) => {
      const { defaultValue } = item;
      if (!isNullOrUnDef(defaultValue)) {
        defaultFormModel[item.key] = defaultValue;
        formModel[item.key] = defaultValue;
      }
    });
  };

  const emit = defineEmits(['update:formRef', 'onReset', 'onFinish']);

  const formAction = useForm({
    emit,
    formProps,
    formRef,
    defaultFormModel,
    formModel,
  });

  defineExpose({
    ...formAction,
  });

  onMounted(() => {
    initDefault();
  });
</script>

<template>
  <n-form :model="formModel" ref="formRef" v-bind="formProps">
    <n-grid v-bind="gridPropsInfo" responsive="screen">
      <n-gi v-bind="schema.giProps" v-for="schema in columns" :key="schema.key">
        <n-form-item :label="schema.label" :path="schema.key">
          <!--标签名右侧温馨提示-->
          <template #label v-if="schema.tooltip">
            {{ schema.label }}
            <LabelMessageVue :tooltip="schema.tooltip" />
          </template>

          <!--判断插槽-->
          <template v-if="schema.slot">
            <slot
              :name="schema.slot"
              :model="formModel"
              :field="schema.key"
              :value="formModel[schema.key]"
            ></slot>
          </template>

          <!--动态渲染表单组件-->
          <FormComponent
            v-else-if="schema.valueType"
            v-model="formModel[schema.key]"
            :valueType="schema.valueType"
            :fieldProps="schema.fieldProps"
          />
        </n-form-item>
      </n-gi>
      <!--提交 重置 展开 收起 按钮-->
      <n-gi :suffix="true" v-if="submitter">
        <Actions
          v-bind="submitter"
          v-model:collapsed="collapsed"
          @on-finish="formAction.submit"
          @on-reset="formAction.resetFields"
        />
      </n-gi>
    </n-grid>
  </n-form>
</template>

<style lang="less" scoped></style>
